package pers.cz.resource;

import pers.cz.tools.StringUtils;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.*;

/**
 * @program: JefConfig
 * @description: 基于url的资源加载器
 * @author: Cheng Zhi
 * @create: 2022-07-11 21:47
 **/
public class UrlResourceLoader extends AbstractJefResourceLoader {

    private URLClassLoader urlClassLoader;


    public UrlResourceLoader() {

    }

    /**
     * 构造器  初始化一个UrlCalssLoader
     * @param envURLS
     */
    public UrlResourceLoader(EnvURL... envURLS) {

        Set<URL> urlSet = new LinkedHashSet<URL>();
        // 获取路径分割符
        String splitSymbol = System.getProperty("path.separator");
        for (EnvURL env : envURLS) {

            switch (env) {
                case PATH: // path环境变量
                    String pathEnv = System.getenv("PATH");
                    for (String path : StringUtils.split(pathEnv, splitSymbol)) {
                        add(urlSet, path);
                    }
                    break;
                case JAVA_LIBRARY_PATH: // lib路径
                    String libraryPath = System.getProperty("java.library.path");
                    for (String path : StringUtils.split(libraryPath, splitSymbol)) {
                        add(urlSet, path);
                    }
                    break;
                case JAVA_HOME:
                    add(urlSet, System.getProperty("java.home"));
                    break;
                case USER_DIR:
                    add(urlSet, System.getProperty("user.dir"));
                    break;
                case TEMP_DIR:
                    add(urlSet, System.getProperty("temp.dir"));
                    break;
                case USER_HOME:
                    add(urlSet, System.getProperty("java.class.path"));
                    break;

                case JAVA_CLASS_PATH:// 系统类加载器加载的所有路径，多个路径
                    String classPath = System.getProperty("java.class.path");
                    for (String path : StringUtils.split(classPath, splitSymbol)) {
                        add(urlSet, path);
                    }
                    break;
                case SYSTEM_TMP:
                    add(urlSet, System.getenv("TEMP"));
                    break;
                case WINDIR:  // 系统安装目录
                    add(urlSet, System.getenv("windir"));
                    break;
            }
        }
        URL[] urls = urlSet.toArray(new URL[urlSet.size()]);
        setPerferUrl(urls);
    }

    /**
     * 根据url获取文件
     * @param name
     * @return
     */
    @Override
    public URL getResource(String name) {

        if (name.startsWith("//")) {

            File file = new File(name.substring(1));
            if (file.exists()) {
                // 如果路径存在直接返回URL
                return super.toUrl(file);
            }
            // 如果不存在继续向下处理
            name = name.substring(2);
        }

        if (name.startsWith("/")) {
            name = name.substring(1);
        }

        if (urlClassLoader != null) {
            return urlClassLoader.findResource(name);
        }

        return null;
    }

    @Override
    public List<URL> getResources(String name) {
        if (name.startsWith("//")) {

            File file = new File(name.substring(1));
            if (file.exists()) {
                // 如果路径存在直接返回URL
                return Arrays.asList(super.toUrl(file));
            }
            // 如果不存在继续向下处理
            name = name.substring(2);
        }

        if (name.startsWith("/")) {
            name = name.substring(1);
        }

        List<URL> result = new ArrayList<URL>();
        try {
            if (urlClassLoader != null) {
                for (Enumeration<URL> e = urlClassLoader.findResources(name); e.hasMoreElements();) {
                    result.add(e.nextElement());
                }
            }
        } catch (IOException e) {
            throw new IllegalStateException(e.getMessage());
        }

        return result;
    }

    private void setPerferUrl(URL[] array) {
        this.urlClassLoader = new URLClassLoader(array);
    }

    private void add(Set<URL> set, String path) {

        if (path == null || path.length() == 0) {
            return;
        }

        try {
            File file = new File(path);
            /**
             * file.toURL() 如果路径中包含空格将会以%20转义
             * file.toURI().toURL() 空格会保留原样
             */
            set.add(file.toURI().toURL());
        } catch (Exception e) {

        }
    }

    public static enum EnvURL {
        PATH,
        JAVA_LIBRARY_PATH,  // jar包路径
        JAVA_HOME,          // jdk安装路径
        USER_DIR,           // 用户文件夹
        TEMP_DIR,           // 临时文件夹
        USER_HOME,          // 用户根目录
        JAVA_CLASS_PATH,    // 类路径
        SYSTEM_TMP,         // 系统路径
        WINDIR              // windows目录
    }
}
